﻿/*
* Copyright (c) 2010-2012 Tesla Engine Group
* 
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* 
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/


using System;
using System.Windows.Forms;
using Tesla.Math;

namespace Tesla.Windows.Core {
    /// <summary>
    /// RenderControl is a specialized control geared towards rendering graphics. RenderControl is a non-primary window
    /// and needs to be added to a container. This is useful for a 3D screen in a win forms application. It can be added to an empty
    /// form and used for games and the like, acting similar to a RenderForm.
    /// </summary>
    public class RenderControl : Control, IRenderControl {
        private bool _allowUserResize;
        private bool _mouseVisible;
        private bool _mouseHidden;

        /// <summary>
        /// Resize event for when the user resizes the control.
        /// </summary>
        public event EventHandler UserResized;

        /// <summary>
        /// Gets or sets if the control can be resized by the user. This will set the form that the control is owned by to be resizable.
        /// </summary>
        public bool AllowUserResizing {
            get {
                return _allowUserResize;
            }
            set {
                _allowUserResize = value;
                Form f = FindForm();
                if(f == null) {
                    return;
                }
                if(value) {
                    f.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Sizable;
                } else {
                    f.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
                }
            }
        }

        /// <summary>
        /// Gets the client bounds of the control.
        /// </summary>
        public Rectangle ClientBounds {
            get {
                System.Drawing.Point p = base.PointToScreen(System.Drawing.Point.Empty);
                return new Rectangle(p.X, p.Y, base.ClientSize.Width, base.ClientSize.Height);
            }
        }

        /// <summary>
        /// Gets or sets if the mouse should be visible when it is over the control.
        /// </summary>
        public bool IsMouseVisible {
            get {
                return _mouseVisible;
            }
            set {
                if(_mouseVisible != value) {
                    _mouseVisible = value;
                    if(_mouseVisible) {
                        if(_mouseHidden) {
                            Cursor.Show();
                            _mouseHidden = false;
                        }
                    } else {
                        if(!_mouseHidden) {
                            Cursor.Hide();
                            _mouseHidden = true;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Gets if the control is minimized.
        /// </summary>
        public bool IsMinimized {
            get {
                return base.ClientSize == System.Drawing.Size.Empty;
            }
        }

        /// <summary>
        /// Creates a new RenderControl.
        /// </summary>
        /// <param name="title">Control's title text</param>
        /// <param name="width">Width of the control</param>
        /// <param name="height">Height of the control</param>
        public RenderControl(String title, int width, int height) {
            base.SuspendLayout();

            base.ClientSize = new System.Drawing.Size(width, height);
            base.Text = title;
            base.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.Opaque, true);
            base.CausesValidation = false;
            base.ResizeRedraw = true;
            base.MouseEnter += new EventHandler(RenderForm_MouseEnter);
            base.MouseLeave += new EventHandler(RenderForm_MouseLeave);
            base.Resize += new EventHandler(RenderForm_Resize);
            base.ResumeLayout(false);
        }

        protected void OnUserResized() {
            if(UserResized  != null) {
                UserResized(this, EventArgs.Empty);
            }
        }

        private void RenderForm_MouseEnter(object sender, EventArgs e) {
            if(!_mouseVisible && !_mouseHidden) {
                Cursor.Hide();
                _mouseHidden = true;
            }
        }

        private void RenderForm_MouseLeave(object sender, EventArgs e) {
            if(_mouseHidden) {
                Cursor.Show();
                _mouseHidden = false;
            }
        }

        private void RenderForm_Resize(object sender, EventArgs e) {
            if(!IsMinimized) {
                OnUserResized();
            }
        }

        protected override void OnPaintBackground(PaintEventArgs e) {
            //Do nothing
        }

        protected override void WndProc(ref System.Windows.Forms.Message m) {
            switch(m.Msg) {
                //WM_SIZE
                 case 0x0005:
                   RenderForm_Resize(this, EventArgs.Empty);
                  break;
            }
            base.WndProc(ref m);
        }

        private void InitializeComponent() {
            this.SuspendLayout();
            this.ResumeLayout(false);

        }

    }
}
